home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / config / winnt / ld.c next >
C/C++ Source or Header  |  1994-11-18  |  6KB  |  261 lines

  1. /* Call Windows NT 3.x linker.
  2.    Copyright (C) 1994 Free Software Foundation, Inc.
  3.    Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #include "config.h"
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <process.h>
  28.  
  29. /* These can be set by command line arguments */
  30. char *linker_path = 0;
  31. int verbose = 0;
  32.  
  33. int link_arg_max = -1;
  34. char **link_args = (char **) 0;
  35. int link_arg_index = -1;
  36.  
  37. char *search_dirs = ".";
  38.  
  39. static int is_regular_file (char *name);
  40.  
  41. static void
  42. addarg (str)
  43.      char *str;
  44. {
  45.   int i;
  46.  
  47.   if (++link_arg_index >= link_arg_max)
  48.     {
  49.       char **new_link_args
  50.     = (char **) calloc (link_arg_max + 1000, sizeof (char *));
  51.  
  52.       for (i = 0; i <= link_arg_max; i++)
  53.     new_link_args [i] = link_args [i];
  54.  
  55.       if (link_args)
  56.     free (link_args);
  57.  
  58.       link_arg_max += 1000;
  59.       link_args = new_link_args;
  60.     }
  61.  
  62.   link_args [link_arg_index] = str;
  63. }
  64.  
  65. static char *
  66. locate_file (file_name, path_val)
  67.      char *file_name;
  68.      char *path_val;
  69. {
  70.   char buf [1000];
  71.   int file_len = strlen (file_name);
  72.   char *end_path = path_val + strlen (path_val);
  73.   char *ptr;
  74.  
  75.   /* Handle absolute pathnames */
  76.   if (file_name [0] == '/' || file_name [0] == DIR_SEPARATOR
  77.       || isalpha (file_name [0]) && file_name [1] == ':')
  78.     {
  79.       strncpy (buf, file_name, sizeof buf);
  80.       buf[sizeof buf - 1] = '\0';
  81.       if (is_regular_file (buf))
  82.     return strdup (buf);
  83.       else
  84.     return 0;
  85.   }
  86.  
  87.   if (! path_val)
  88.     return 0;
  89.  
  90.   for (;;)
  91.     {
  92.       for (; *path_val == PATH_SEPARATOR ; path_val++)
  93.     ;
  94.       if (! *path_val)
  95.     return 0;
  96.  
  97.       for (ptr = buf; *path_val && *path_val != PATH_SEPARATOR; )
  98.     *ptr++ = *path_val++;
  99.  
  100.       ptr--;
  101.       if (*ptr != '/' && *ptr != DIR_SEPARATOR)
  102.     *++ptr = DIR_SEPARATOR;
  103.  
  104.       strcpy (++ptr, file_name);
  105.  
  106.       if (is_regular_file (buf))
  107.     return strdup (buf);
  108.     }
  109.  
  110.   return 0;
  111. }
  112.  
  113. static char *
  114. expand_lib (name)
  115.      char *name;
  116. {
  117.   char *lib, *lib_path;
  118.  
  119.   lib = malloc (strlen (name) + 6);
  120.   strcpy (lib, "lib");
  121.   strcat (lib, name);
  122.   strcat (lib, ".a");
  123.   lib_path = locate_file (lib, search_dirs);
  124.   if (!lib_path)
  125.     {
  126.       fprintf (stderr, "Couldn't locate library: %s\n", lib);
  127.       exit (1);
  128.     }
  129.  
  130.   return lib_path;
  131. }
  132.  
  133. static int
  134. is_regular_file (name)
  135.      char *name;
  136. {
  137.   int ret;
  138.   struct stat statbuf;
  139.  
  140.   ret = stat(name, &statbuf);
  141.   return !ret && S_ISREG (statbuf.st_mode);
  142. }
  143.  
  144. static void
  145. process_args (p_argc, argv)
  146.      int *p_argc;
  147.      char *argv[];
  148. {
  149.   int i, j;
  150.  
  151.   for (i = 1; i < *p_argc; i++)
  152.     {
  153.       /* -v turns on verbose option here and is passed on to gcc */
  154.       if (! strcmp (argv [i], "-v"))
  155.     verbose = 1;
  156.     }
  157. }
  158.  
  159. main (argc, argv)
  160.      int argc;
  161.      char *argv[];
  162. {
  163.   int i;
  164.   int done_an_ali = 0;
  165.   int file_name_index;
  166.   char *pathval = getenv ("PATH");
  167.   char *spawn_args [5];
  168.   char *tmppathval = malloc (strlen (pathval) + 3);
  169.  
  170.   strcpy (tmppathval, ".;");
  171.   pathval = strcat (tmppathval, pathval);
  172.  
  173.   process_args (&argc , argv);
  174.  
  175.   linker_path = locate_file ("link32.exe", pathval);
  176.   if (!linker_path)
  177.     {
  178.       linker_path = locate_file ("link.exe", pathval);
  179.       if (!linker_path)
  180.     {
  181.       fprintf (stderr, "Couldn't locate link32 or link\n");
  182.       exit (1);
  183.     }
  184.     }
  185.  
  186.   addarg (linker_path);
  187.  
  188.   for (i = 1; i < argc; i++)
  189.     {
  190.       int arg_len = strlen (argv [i]);
  191.  
  192.       if (!strcmp (argv [i], "-o"))
  193.     {
  194.       char *buff, *ptr;
  195.       int out_len;
  196.  
  197.       i++;
  198.       out_len = strlen (argv[i]) + 10;
  199.       buff = malloc (out_len);
  200.       strcpy (buff, "-out:");
  201.       strcat (buff, argv[i]);
  202.       ptr = strstr (buff, ".exe");
  203.       if (ptr == NULL || strlen (ptr) != 4)
  204.         strcat (buff, ".exe");
  205.       addarg (buff);
  206.       addarg ("-debug:full -debugtype:coff");
  207.     }
  208.       else if (arg_len > 2 && !strncmp (argv [i], "-L", 2))
  209.     {
  210.       char *nbuff, *sdbuff;
  211.       int j, new_len, search_dirs_len;
  212.  
  213.       new_len = strlen (&argv[i][2]);
  214.       search_dirs_len = strlen (search_dirs);
  215.  
  216.       nbuff = malloc (new_len + 1);
  217.       strcpy (nbuff, &argv[i][2]);
  218.  
  219.       for (j = 0; j < new_len; j++)
  220.         if (nbuff[j] == '/') nbuff[j] = DIR_SEPARATOR;
  221.  
  222.       sdbuff = malloc (search_dirs_len + new_len + 2);
  223.       strcpy (sdbuff, search_dirs);
  224.       sdbuff[search_dirs_len] = PATH_SEPARATOR;
  225.       sdbuff[search_dirs_len+1] = 0;
  226.       strcat (sdbuff, nbuff);
  227.  
  228.       if (search_dirs)
  229.         free (search_dirs);
  230.  
  231.       search_dirs = sdbuff;
  232.     }
  233.  
  234.       else if (arg_len > 2 && !strncmp (argv [i], "-l", 2))
  235.     addarg (expand_lib (&argv[i][2]));
  236.     else if (!strcmp (argv [i], "-v")) 
  237.       ;
  238.     else
  239.       addarg (argv [i]);
  240.     }
  241.  
  242.   addarg (NULL);
  243.  
  244.   if (verbose)
  245.     {
  246.       int i;
  247.  
  248.       for (i = 0; i < link_arg_index; i++)
  249.     printf ("%s ", link_args [i]);
  250.       putchar ('\n');
  251.     }
  252.  
  253.   if (spawnvp (P_WAIT, linker_path, (const char * const *)link_args) != 0)
  254.     {
  255.       fprintf (stderr, "Error executing %s\n", link_args[0]);
  256.       exit (1);
  257.     }
  258.  
  259.   exit (0);
  260. }
  261.